﻿//Copyright (C) <2013>  <jonathan cleeve norton> All Rights Reserved 
//Contact jon.norton@fin-plus.co.uk website <http://www.fin-plus.co.uk/>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using FinPlusCommon;
using log = Logger.Logger;
using u = FinPlusUtility.Utility;

namespace FinPlusComponents
{
    public class FinPlusTradeRegister : FinPlusComponent
    {
        public override string Id { get; set; }
        public override string[] States { get { return new string[] { }; } }
        public override string[] TestStates { get { return new string[] { "IsValid" }; } }
        public override IFinPlusFunctions Model { get { return null; } }
        public override string ModelTest { get { return null; } }
        public override bool IsValid { get; set; }

        private enum Params { ReceiveQuoteAction, ParseTradeAction, InstrumentType }
        private enum DockControls { FinPlusDataConn, FinPlusChildService, Default }
        private enum Connection { TradeAdaptors, Exception }
        
        private IFinPlusComponent _tradeAdaptorConn;
        private IFinPlusFunctions _tradeAdaptors;

        //construct
        public FinPlusTradeRegister()
        {
            IsValid = true;
        }

        //common control interface
        public override void Dock(object component, string dock)
        {
            try
            {
                switch (u.EnumTryParse<DockControls>(component.GetType().Name, DockControls.Default))
                {
                    case DockControls.FinPlusChildService:
                    case DockControls.FinPlusDataConn:
                    case DockControls.Default: AddConnection((IFinPlusComponent)component, dock); break;
                }
            }
            catch (Exception e)
            {
                IsValid = log.Log(Logger.Level.Error, Id, Config, e.Message, e);
            }
        }

        public override void Initialise()
        {

        }

        public override void Dispose()
        {
            throw new NotImplementedException();
        }

        public override void CommandRouter(IFinPlusFunction func)
        {
            try
            {
                CaptureCommand(func);

                switch ((Commands)Enum.Parse(typeof(Commands), func.Name, true))
                {
                    case Commands.QuoteAccept: QuoteParse(func); break;
                    case Commands.QuoteAcceptPublish: QuoteParse(func); break;
                    default: throw new Exception(string.Format("event not recognised {0}", func.Name));
                }
            }
            catch (Exception e)
            {
               IsValid = log.Log(Logger.Level.Error, Id, Config, e.Message, e);
            }
        }

        //private
        private void AddConnection(IFinPlusComponent conn, string dock)
        {
            try
            {
                switch (u.EnumTryParse<Connection>(dock, Connection.Exception))
                {
                    case Connection.TradeAdaptors: AddTradeAdaptors(conn); break;
                    case Connection.Exception: throw new NotImplementedException();
                }
            }
            catch (Exception e)
            {
                log.Log(Logger.Level.Error, Id, Config, e.Message, e);
            }
        }

        private void AddTradeAdaptors(IFinPlusComponent conn)
        {
            try
            {
                _tradeAdaptorConn = conn;
                _tradeAdaptors = _tradeAdaptorConn.Model;
                foreach (var tradeAdaptor in _tradeAdaptors.Values)
                    tradeAdaptor.Get(Params.ReceiveQuoteAction.ToString(), Quote_Accepted);
            }
            catch (Exception e)
            {
                log.Log(Logger.Level.Error, Id, Config, e.Message, e);
            }
        }

        private bool QuoteParse(IFinPlusFunction func)
        {
            try
            {
                //TODO save execution for audit and check
                //Save exection for reconcile to parse trades and audit

                //send back to adaptor for Trade parser
                foreach (var tradeAdaptor in _tradeAdaptors.Values.Where(f => f[Params.InstrumentType.ToString()].Equals(func[Params.InstrumentType.ToString()])))
                    tradeAdaptor.Get(Params.ParseTradeAction.ToString()).Set(func); //to trade engine

            }
            catch (Exception e)
            {
                log.Log(Logger.Level.Error, Id, Config, e.Message, e);
            }

            return true;
        }

        //cmds
        private new enum Commands { QuoteAccept, QuoteAcceptPublish };

        //events
        private void Quote_Accepted(object sender, PropertyChangedEventArgs a) { CommandRouter((IFinPlusFunction)((IFinPlusItem)sender).Object); }//QuoteAccept && QuotePublishAccept
    }
}
